
#include "StdAfx.h"
#include "BitmapRender.h"
#include "BitmapDC.h"

CBitmapRender::CBitmapRender(CDC *pDC, CBitmap *pBitmap)
	: m_pDC(pDC)
	, m_pBitmap(pBitmap)
{
}

CBitmapRender::~CBitmapRender(void)
{
}

void CBitmapRender::Draw(int xDest, int yDest, int nDestWidth, int nDestHeight, int xSrc, int ySrc, BOOL bTransparent, COLORREF clrTranparent)
{
	CBitmapDC bmpDC(m_pDC, m_pBitmap);
	if(bTransparent)
	{
		m_pDC->TransparentBlt(xDest, yDest, nDestWidth, nDestHeight, &bmpDC, xSrc, ySrc, nDestWidth, nDestHeight, clrTranparent);
	}
	else
	{
		m_pDC->BitBlt(xDest, yDest, nDestWidth, nDestHeight, &bmpDC, xSrc, ySrc, SRCCOPY);
	}
}

void CBitmapRender::StretchDraw(const CRect& rectDest, const CRect& rectSource, BOOL bVertical)
{
	if(bVertical)
	{
		VerticalStretch(rectDest, rectSource);
	}
	else
	{
		HorizontalStretch(rectDest, rectSource);
	}
}

void CBitmapRender::HorizontalStretch(const CRect& rectDest, const CRect& rectSource)
{
	int nSide = (rectSource.Width()-1)/2;
	int xDest = rectDest.left;
	int yDest = rectDest.top;
	int height = rectDest.Height();
	int xSrc = rectSource.left;
	int ySrc = rectSource.top;

	CBitmapDC bmpDC(m_pDC, m_pBitmap);
	m_pDC->BitBlt(xDest, yDest, nSide, height, &bmpDC, xSrc, ySrc, SRCCOPY);
	xDest += nSide;
	xSrc += nSide;
	int nDestMidWidth = rectDest.Width()-rectSource.Width()+1;
	if(nDestMidWidth > 0)
	{
		m_pDC->StretchBlt(xDest, yDest, nDestMidWidth, height, &bmpDC, xSrc, ySrc, 1, height, SRCCOPY);
		xDest += nDestMidWidth;
	}
	xSrc += 1;

	m_pDC->BitBlt(xDest, yDest, nSide, height, &bmpDC, xSrc, ySrc, SRCCOPY);
}

void CBitmapRender::VerticalStretch(const CRect& rectDest, const CRect& rectSource)
{
	int nSide = (rectSource.Height()-1)/2;
	int xDest = rectDest.left;
	int yDest = rectDest.top;
	int width = rectDest.Width();
	int xSrc = rectSource.left;
	int ySrc = rectSource.top;

	CBitmapDC bmpDC(m_pDC, m_pBitmap);
	m_pDC->BitBlt(xDest, yDest, width, nSide, &bmpDC, xSrc, ySrc, SRCCOPY);
	yDest += nSide;
	ySrc += nSide;
	int nDestMidHeight = rectDest.Height()-rectSource.Height()+1;
	if(nDestMidHeight > 0)
	{
		m_pDC->StretchBlt(xDest, yDest, width, nDestMidHeight, &bmpDC, xSrc, ySrc, width, nDestMidHeight, SRCCOPY);
		yDest += nDestMidHeight;
	}
	ySrc += 1;

	m_pDC->BitBlt(xDest, yDest, width, nSide, &bmpDC, xSrc, ySrc, SRCCOPY);
}

void CBitmapRender::FullStretch(const CRect& rectDest, const CRect& rectSource)
{
	int nHorzSide = (rectSource.Width()-1)/2;
	int nVertSide = (rectSource.Height()-1)/2;
	int xDest = rectDest.left;
	int yDest = rectDest.top;
	int xSrc = rectSource.left;
	int ySrc = rectSource.top;
	int nDestMidWidth = rectDest.Width()-rectSource.Width()+1;
	int nDestMidHeight = rectDest.Height()-rectSource.Height()+1;

	CBitmapDC bmpDC(m_pDC, m_pBitmap);
	m_pDC->BitBlt(xDest, yDest, nHorzSide, nVertSide, &bmpDC, xSrc, ySrc, SRCCOPY);
	xDest += nHorzSide;
	xSrc += nHorzSide;
	if(nDestMidWidth > 0)
	{
		m_pDC->StretchBlt(xDest, yDest, nDestMidWidth, nVertSide, &bmpDC, xSrc, ySrc, 1, nVertSide, SRCCOPY);
		xDest += nDestMidWidth;
	}
	xSrc += 1;
	m_pDC->BitBlt(xDest, yDest, nHorzSide, nVertSide, &bmpDC, xSrc, ySrc, SRCCOPY);

	xSrc = rectSource.left;
	ySrc += nVertSide;
	yDest += nVertSide;
	xDest = rectDest.left;
	if(nDestMidHeight > 0)
	{
		m_pDC->StretchBlt(xDest, yDest, nHorzSide, nDestMidHeight, &bmpDC, xSrc, ySrc, nHorzSide, 1, SRCCOPY);
		xSrc += nHorzSide;
		xDest += nHorzSide;
		if(nDestMidWidth > 0)
		{
			m_pDC->StretchBlt(xDest, yDest, nDestMidWidth, nDestMidHeight, &bmpDC, xSrc, ySrc, 1, 1, SRCCOPY);
			xDest += nDestMidWidth;
		}
		xSrc += 1;
		m_pDC->StretchBlt(xDest, yDest, nHorzSide, nDestMidHeight, &bmpDC, xSrc, ySrc, nHorzSide, 1, SRCCOPY);
		yDest += nDestMidHeight;
	}
	ySrc += 1;
	xSrc = rectSource.left;
	xDest = rectDest.left;

	m_pDC->BitBlt(xDest, yDest, nHorzSide, nVertSide, &bmpDC, xSrc, ySrc, SRCCOPY);
	xDest += nHorzSide;
	xSrc += nHorzSide;
	if(nDestMidWidth > 0)
	{
		m_pDC->StretchBlt(xDest, yDest, nDestMidWidth, nVertSide, &bmpDC, xSrc, ySrc, 1, nVertSide, SRCCOPY);
		xDest += nDestMidWidth;
	}
	xSrc += 1;
	m_pDC->BitBlt(xDest, yDest, nHorzSide, nVertSide, &bmpDC, xSrc, ySrc, SRCCOPY);
}

void CBitmapRender::BorderStretch(const CRect& rectDest, const CRect& rectSource)
{
	int nHorzSide = (rectSource.Width()-1)/2;
	int nVertSide = (rectSource.Height()-1)/2;
	int xDest = rectDest.left;
	int yDest = rectDest.top;
	int xSrc = rectSource.left;
	int ySrc = rectSource.top;
	int nDestMidWidth = rectDest.Width()-rectSource.Width()+1;
	int nDestMidHeight = rectDest.Height()-rectSource.Height()+1;

	CBitmapDC bmpDC(m_pDC, m_pBitmap);
	m_pDC->BitBlt(xDest, yDest, nHorzSide, nVertSide, &bmpDC, xSrc, ySrc, SRCCOPY);
	xDest += nHorzSide;
	xSrc += nHorzSide;
	if(nDestMidWidth > 0)
	{
		m_pDC->StretchBlt(xDest, yDest, nDestMidWidth, nVertSide, &bmpDC, xSrc, ySrc, 1, nVertSide, SRCCOPY);
		xDest += nDestMidWidth;
	}
	xSrc += 1;
	m_pDC->BitBlt(xDest, yDest, nHorzSide, nVertSide, &bmpDC, xSrc, ySrc, SRCCOPY);

	xSrc = rectSource.left;
	ySrc += nVertSide;
	yDest += nVertSide;
	xDest = rectDest.left;
	if(nDestMidHeight > 0)
	{
		m_pDC->StretchBlt(xDest, yDest, nHorzSide, nDestMidHeight, &bmpDC, xSrc, ySrc, nHorzSide, 1, SRCCOPY);
		xSrc += (nHorzSide+1);
		xDest += (nHorzSide+(nDestMidWidth>0?nDestMidWidth:0));
		m_pDC->StretchBlt(xDest, yDest, nHorzSide, nDestMidHeight, &bmpDC, xSrc, ySrc, nHorzSide, 1, SRCCOPY);
		yDest += nDestMidHeight;
	}
	ySrc += 1;
	xSrc = rectSource.left;
	xDest = rectDest.left;

	m_pDC->BitBlt(xDest, yDest, nHorzSide, nVertSide, &bmpDC, xSrc, ySrc, SRCCOPY);
	xDest += nHorzSide;
	xSrc += nHorzSide;
	if(nDestMidWidth > 0)
	{
		m_pDC->StretchBlt(xDest, yDest, nDestMidWidth, nVertSide, &bmpDC, xSrc, ySrc, 1, nVertSide, SRCCOPY);
		xDest += nDestMidWidth;
	}
	xSrc += 1;
	m_pDC->BitBlt(xDest, yDest, nHorzSide, nVertSide, &bmpDC, xSrc, ySrc, SRCCOPY);
}

void CBitmapRender::BorderStretch(const CRect& rectDest, const CRect& rectSource, COLORREF clrFillColor)
{
	int nHorzSide = (rectSource.Width()-1)/2;
	int nVertSide = (rectSource.Height()-1)/2;
	int xDest = rectDest.left;
	int yDest = rectDest.top;
	int xSrc = rectSource.left;
	int ySrc = rectSource.top;
	int nDestMidWidth = rectDest.Width()-rectSource.Width()+1;
	int nDestMidHeight = rectDest.Height()-rectSource.Height()+1;

	CBitmapDC bmpDC(m_pDC, m_pBitmap);
	m_pDC->BitBlt(xDest, yDest, nHorzSide, nVertSide, &bmpDC, xSrc, ySrc, SRCCOPY);
	xDest += nHorzSide;
	xSrc += nHorzSide;
	if(nDestMidWidth > 0)
	{
		m_pDC->StretchBlt(xDest, yDest, nDestMidWidth, nVertSide, &bmpDC, xSrc, ySrc, 1, nVertSide, SRCCOPY);
		xDest += nDestMidWidth;
	}
	xSrc += 1;
	m_pDC->BitBlt(xDest, yDest, nHorzSide, nVertSide, &bmpDC, xSrc, ySrc, SRCCOPY);

	xSrc = rectSource.left;
	ySrc += nVertSide;
	yDest += nVertSide;
	xDest = rectDest.left;
	if(nDestMidHeight > 0)
	{
		m_pDC->StretchBlt(xDest, yDest, nHorzSide, nDestMidHeight, &bmpDC, xSrc, ySrc, nHorzSide, 1, SRCCOPY);
		xSrc += nHorzSide;
		xDest += nHorzSide;
		if(nDestMidWidth > 0)
		{
			m_pDC->FillSolidRect(xDest, yDest, nDestMidWidth, nDestMidHeight, clrFillColor);
			xDest += nDestMidWidth;
		}
		xSrc += 1;
		m_pDC->StretchBlt(xDest, yDest, nHorzSide, nDestMidHeight, &bmpDC, xSrc, ySrc, nHorzSide, 1, SRCCOPY);
		yDest += nDestMidHeight;
	}
	ySrc += 1;
	xSrc = rectSource.left;
	xDest = rectDest.left;

	m_pDC->BitBlt(xDest, yDest, nHorzSide, nVertSide, &bmpDC, xSrc, ySrc, SRCCOPY);
	xDest += nHorzSide;
	xSrc += nHorzSide;
	if(nDestMidWidth > 0)
	{
		m_pDC->StretchBlt(xDest, yDest, nDestMidWidth, nVertSide, &bmpDC, xSrc, ySrc, 1, nVertSide, SRCCOPY);
		xDest += nDestMidWidth;
	}
	xSrc += 1;
	m_pDC->BitBlt(xDest, yDest, nHorzSide, nVertSide, &bmpDC, xSrc, ySrc, SRCCOPY);
}


